package com.zzjx.log.demo;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.threadpool.TtlExecutors;

import java.io.InputStream;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;

/**
 * @author zhaojiaxu
 * @date 2021/07/20 08:42
 * 为了更深刻理解ThreadLocal存在父子线程传递问题
 **/
public class TransmittableThreadLocalTest {
    public static void main(String[] args) throws InterruptedException {
//        //测试ThreadLocal可不可以进行线程传递，结果为null
//        ThreadLocal<String> stringThreadLocal = new ThreadLocal<>();
//        stringThreadLocal.set("zzjx");
//        Thread thread = new Thread(() -> {
//            String s = stringThreadLocal.get();
//            System.out.print(s);
//        });
//        thread.start();
//        //那么我们有没有什么思路进行线程之间的父子传递呢？
//        //
//        ThreadLocal<String> parentTraceid = new InheritableThreadLocal<>();
//        parentTraceid.set("traceId:38127121");
//        Thread thread1 = new Thread(() -> {
//            String s = parentTraceid.get();
//            System.out.print(s);
//        });
//        thread1.start();
        //我们线程池测试一下
//        ThreadLocal<String> localThreadLocal = new InheritableThreadLocal<>();
//        ExecutorService executorService = Executors.newFixedThreadPool(1);
//        CountDownLatch countDownLatch1 = new CountDownLatch(1);
//        CountDownLatch countDownLatch2 = new CountDownLatch(1);
//        localThreadLocal.set("我是主线程1");
//        executorService.submit(()->{
//            System.out.println(String.format("1Thread-%s",localThreadLocal.get()));
//            countDownLatch1.countDown();
//        });
//        countDownLatch1.await();
//        System.out.println(String.format("%s",localThreadLocal.get()));
//        System.out.println("-------------------------");
//        System.out.println("-------------------------");
//        localThreadLocal.set("我是主线程2");
//        executorService.submit(()->{
//            System.out.println(String.format("2Thread-%s",localThreadLocal.get()));
//            countDownLatch2.countDown();
//        });
//        countDownLatch2.await();
//        System.out.println(String.format("%s",localThreadLocal.get()));
//        //关闭线程池
//        executorService.shutdown();

        TransmittableThreadLocal<String> objectTransmittableThreadLocal = new TransmittableThreadLocal<>();
        //     ExecutorService executorService = Executors.newFixedThreadPool(1);
        // 需要注意的是，使用TTL的时候，要想传递的值不出问题，线程池必须得用TTL加一层代理（下面会讲这样做的目的）
        ExecutorService ttlExecutorService = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(1));

        CountDownLatch countDownLatch1 = new CountDownLatch(1);
        CountDownLatch countDownLatch2 = new CountDownLatch(1);
        ThreadLocal tl = new TransmittableThreadLocal<>(); //这里采用TTL的实现
        tl.set("我是主线程1");
        ttlExecutorService.submit(() -> {
            System.out.println(String.format("1Thread-%s", tl.get()));
            countDownLatch1.countDown();
        });
        countDownLatch1.await();

        tl.set("我是主线程2");
        ttlExecutorService.submit(() -> {
            System.out.println(String.format("2Thread-%s", tl.get()));
            countDownLatch2.countDown();
        });
        countDownLatch2.await();
        ttlExecutorService.shutdown();
        //  executorService.shutdown();
    }


}

